package org.objective.base;

import org.objective.service.Loader;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author gus
 */
public abstract class BaseFieldCollection<T extends BaseDomainObject, TOwner extends BaseObject> implements ObjectCollection<T, TOwner>
{
    private final List<T> fields = new ArrayList<T>(10);
    private final TOwner owner;
    protected final Construction<T> ctor;

    public BaseFieldCollection(TOwner owner, Construction<T> ctor)
    {
        if (owner == null)
        {
            throw new IllegalArgumentException("owner");
        }
        if (ctor == null)
        {
            throw new IllegalArgumentException("ctor");
        }
        this.owner = owner;
        this.ctor = ctor;
    }

    public TOwner getOwner()
    {
        return owner;
    }

    @Override
    public int size()
    {
        return fields.size();
    }

    @Override
    public boolean isEmpty()
    {
        return fields.isEmpty();
    }

    @Override
    public T get(int id)
    {
        return fields.get(id);
    }

    @Override
    public void load(Loader loader, long[] fieldIdList) throws Exception
    {
        loadFields(loader, fieldIdList);
    }

    protected void loadFields(Loader loader, long[] fieldIdList) throws Exception
    {
        for (long id : fieldIdList)
        {
            owner.getStorage().getObject(id);
        }
    }

    @Override
    public T get(String name)
    {
        for (T field : fields)
        {
            if (field.getName().equalsIgnoreCase(name))
            {
                return field;
            }
        }
        return null;
    }

    @Override
    public T newInstance() throws Exception
    {
        return newInstance(ctor);
    }

    @Override
    public T newInstance(Construction constructionCallback) throws Exception
    {
        T field = constructNew(constructionCallback);
        fields.add(field);
        return field;
    }

    protected abstract T constructNew(Construction<T> constructionCallback) throws Exception;

    @Override
    public T[] toArray()
    {
        return (T[]) fields.toArray(new BaseField[0]);
    }

    @Override
    public T[] toArray(ObjectFilter<T> filter)
    {
        List<T> collection = new ArrayList<T>(fields.size());
        for (T field : fields)
        {
            if (filter.accept(field))
            {
                collection.add(field);
            }
        }
        return (T[]) collection.toArray();
    }

    @Override
    public Iterator<T> iterator()
    {
        return fields.iterator();
    }
}
